﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using AForge.Imaging.Filters;

namespace QuickPhotoFilter
{
    public partial class FilterWindow : Form
    {
        WriteableBitmap writeableBitmap;
        byte[] pixels;
        Bitmap initialPicture, filteredPicture;
        BaseFilter baseFilter;
        Convolution convolutionFilter;
        BaseUsingCopyPartialFilter baseUsingCopyPartialFilter;
        BaseInPlacePartialFilter baseInPlacePartialFilter;

        public FilterWindow()
        {
            InitializeComponent();
            pixels = new byte[(int)(image.Width * image.Height * 4)];
        }

        public WriteableBitmap WriteableBitmap
        {
            get { return writeableBitmap; }
            set
            {
                writeableBitmap = value;
                pixels = new byte[writeableBitmap.PixelWidth * writeableBitmap.PixelHeight * 4];
                writeableBitmap.CopyPixels(pixels, writeableBitmap.PixelWidth * 4, 0);
                initialPicture = new Bitmap(writeableBitmap.PixelWidth, writeableBitmap.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
                for (int i = 0; i < writeableBitmap.PixelWidth; ++i)
                    for (int j = 0; j < writeableBitmap.PixelHeight; ++j)
                    {
                        System.Windows.Media.Color currentPixelColor = QPF.DetermineColor(new System.Windows.Point(i, j), pixels, writeableBitmap.PixelWidth);
                        System.Drawing.Color color = System.Drawing.Color.FromArgb(currentPixelColor.A, currentPixelColor.R, currentPixelColor.G, currentPixelColor.B);
                        initialPicture.SetPixel(i, j, color);
                    }
                Bitmap initialResizedPicture = ResizeBitmap(initialPicture, image.Width, image.Height);
                image.Image = initialResizedPicture;
            }
        }

        public Bitmap InitialPicture { get { return initialPicture; } }

        private void filterBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            filteredPicture = ResizeBitmap(initialPicture, image.Width, image.Height);
            System.Drawing.Imaging.PixelFormat pixelFormat = new System.Drawing.Imaging.PixelFormat();
            baseFilter = null;
            convolutionFilter = null;
            baseUsingCopyPartialFilter = null;
            baseInPlacePartialFilter = null;
            switch (filterBox.SelectedIndex)
            {
                case 0:
                    pixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppRgb;
                    convolutionFilter = new Blur();
                    break;
                case 1:
                    pixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppRgb;
                    baseUsingCopyPartialFilter = new Jitter(7);
                    break;
                case 2:
                    pixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppRgb;
                    baseUsingCopyPartialFilter = new OilPainting(15);
                    break;
                case 3:
                    pixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppRgb;
                    baseInPlacePartialFilter = new Sepia();
                    break;
                case 4:
                    pixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppRgb;
                    baseFilter = new WaterWave()
                    {
                        HorizontalWavesCount = 10,
                        HorizontalWavesAmplitude = 5,
                        VerticalWavesCount = 3,
                        VerticalWavesAmplitude = 15
                    };
                    break;
                case 5:
                    pixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppRgb;
                    baseInPlacePartialFilter = new SaturationCorrection(0.5F);
                    break;
                case 6:
                    pixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppRgb;
                    baseInPlacePartialFilter = new SimplePosterization();
                    break;
            }

            if (baseFilter != null)
                baseFilter.Apply(filteredPicture);
            if (convolutionFilter != null)
                convolutionFilter.ApplyInPlace(filteredPicture);
            if (baseUsingCopyPartialFilter != null)
                baseUsingCopyPartialFilter.ApplyInPlace(filteredPicture);
            if (baseInPlacePartialFilter != null)
                baseInPlacePartialFilter.ApplyInPlace(filteredPicture);
            image.Image = filteredPicture;
        }

        private static Bitmap ResizeBitmap(Bitmap sourceBMP, int width, int height)
        {
            Bitmap result = new Bitmap(width, height);
            using (Graphics g = Graphics.FromImage(result))
                g.DrawImage(sourceBMP, 0, 0, width, height);
            return result;
        }

        private void okButton_Click(object sender, EventArgs e)
        {
            DialogResult = System.Windows.Forms.DialogResult.OK;
            if (baseFilter != null)
                baseFilter.Apply(initialPicture);
            if (convolutionFilter != null)
                convolutionFilter.ApplyInPlace(initialPicture);
            if (baseUsingCopyPartialFilter != null)
                baseUsingCopyPartialFilter.ApplyInPlace(initialPicture);
            if (baseInPlacePartialFilter != null)
                baseInPlacePartialFilter.ApplyInPlace(initialPicture);
            Close();
        }
    }
}
